package io.cici.cc.mybatis.plus.core.tagHandler;

import io.cici.cc.mybatis.lite.builder.BuilderException;
import io.cici.cc.mybatis.lite.sql_source.scripting.tag.ChooseTag;
import io.cici.cc.mybatis.lite.sql_source.scripting.tag.Tag;
import io.cici.cc.mybatis.plus.core.MybatisXMLScriptBuilder;

import java.util.ArrayList;
import java.util.List;

/**
 * @author huihui
 */
public class ChooseHandler implements TagHandler {
    private final MybatisXMLScriptBuilder mybatisXMLScriptBuilder;

    public ChooseHandler(MybatisXMLScriptBuilder mybatisXMLScriptBuilder) {
        this.mybatisXMLScriptBuilder = mybatisXMLScriptBuilder;
        // Prevent Synthetic Access
    }

    @Override
    public void handleNode(io.cici.cc.mybatis.lite.parse.Node nodeToHandle, List<Tag> targetTagList) {
        List<Tag> whenTags = new ArrayList<>();
        List<Tag> otherwiseTags = new ArrayList<>();
        handleWhenOtherwiseNodes(nodeToHandle, whenTags, otherwiseTags);
        Tag defaultTag = getDefaultSqlNode(otherwiseTags);
        ChooseTag chooseTag = new ChooseTag(whenTags, defaultTag);
        targetTagList.add(chooseTag);
    }

    private void handleWhenOtherwiseNodes(io.cici.cc.mybatis.lite.parse.Node chooseNode, List<Tag> ifTags, List<Tag> defaultTags) {
        List<io.cici.cc.mybatis.lite.parse.Node> childNodeList = chooseNode.getChildNodeList();
        for (io.cici.cc.mybatis.lite.parse.Node childNode : childNodeList) {
            String nodeName = childNode.getNode().getNodeName();
            TagHandler tagHandler = mybatisXMLScriptBuilder.nodeHandlerMap.get(nodeName);
            if (tagHandler instanceof IfHandler) {
                tagHandler.handleNode(childNode, ifTags);
            } else if (tagHandler instanceof OtherwiseHandler) {
                tagHandler.handleNode(childNode, defaultTags);
            }
        }
    }

    private Tag getDefaultSqlNode(List<Tag> defaultTagList) {
        Tag defaultTag = null;
        if (defaultTagList.size() == 1) {
            defaultTag = defaultTagList.get(0);
        } else if (defaultTagList.size() > 1) {
            throw new BuilderException("Too many default (otherwise) elements in choose statement.");
        }
        return defaultTag;
    }
}
